Skip to content

Readonly or mutable engine as per user configuration#65

Merged
konard merged 4 commits into
issue-47-76af108c0f24from
issue-49-3a3011bb1089
Jun 11, 2026
Merged

Readonly or mutable engine as per user configuration#65
konard merged 4 commits into
issue-47-76af108c0f24from
issue-49-3a3011bb1089

Conversation

@konard

@konard konard commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

Implements R-1 / S-1 from the issue #47 case study: a read-only or mutable
engine selected by user configuration. Today LinkNetwork is always mutable;
this adds an enforced read-only mode that composes with existing snapshot
sharing instead of duplicating it.

Fixes #49.

What changed

  • AccessMode { Mutable, ReadOnly } on ParseConfiguration
    (with_access_mode / access_mode). Defaults to Mutable, so existing
    callers see no behavior change.
  • ReadOnlyNetwork — a frozen view produced by LinkNetwork::freeze() /
    as_read_only(). It derefs to &LinkNetwork, exposing every non-mutating
    operation (query, project, reconstruct, verify, serialize) while leaving the
    &mut self mutators unreachable at compile time (there is no DerefMut).
    The network is held behind an Arc, so clones share one allocation.
  • EngineNetwork + LinkNetwork::parse_engine() — the runtime
    boundary that honours the configured access mode. Read-only parsing returns
    the frozen form, and EngineNetwork::as_mutable() rejects mutation with a
    clear ReadOnlyViolation diagnostic.
  • Snapshot interopNetworkSnapshot::as_read_only() /
    from_read_only() reuse the snapshot's Arc<LinkNetwork>, so freezing and
    snapshot versioning share one allocation.

Acceptance criteria

  • ParseConfiguration carries an access mode; default remains Mutable.
  • A read-only view supports every non-mutating public operation and none of
    the mutating ones (compile-time enforced via Deref-without-DerefMut).
  • Tests cover: freeze → query/reconstruct/verify works; mutation is
    impossible (compile_fail doctest) and rejected at the engine boundary
    (ReadOnlyViolation); snapshot interop; Arc sharing.
  • Changelog fragment added (bump: minor).

How to verify

cargo test --all-features access_mode      # unit tests
cargo test --all-features --doc access     # passing + compile_fail doctests
cargo clippy --all-targets --all-features
cargo fmt --check

Read-only usage:

use meta_language::{AccessMode, LinkNetwork, ParseConfiguration};

let configuration = ParseConfiguration::default().with_access_mode(AccessMode::ReadOnly);
let mut engine = LinkNetwork::parse_engine("alpha beta", "plain-text", configuration);

assert!(engine.is_read_only());
assert_eq!(engine.reconstruct_text(), "alpha beta"); // reads work via Deref
assert!(engine.as_mutable().is_err());               // mutation rejected

Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: #49
@konard konard self-assigned this Jun 10, 2026
Add an AccessMode { Mutable, ReadOnly } setting to ParseConfiguration
(default Mutable, no behavior change for existing callers) and a frozen
read-only engine boundary.

- ReadOnlyNetwork: a compile-time read-only view that derefs to
  &LinkNetwork, exposing every non-mutating operation while leaving the
  &mut self mutators unreachable (no DerefMut). Held behind an Arc so
  clones share one allocation.
- LinkNetwork::freeze / as_read_only produce the view; EngineNetwork and
  LinkNetwork::parse_engine honour the configured access mode and reject
  mutation at runtime with a ReadOnlyViolation diagnostic.
- Snapshot interop: NetworkSnapshot::as_read_only / from_read_only reuse
  the snapshot's Arc<LinkNetwork>, composing with snapshot versioning
  instead of duplicating it.
- Tests cover freeze -> query/reconstruct/verify, compile-fail mutation
  (doctest), runtime ReadOnlyViolation, snapshot interop, and Arc sharing.
- Changelog fragment (bump: minor); README usage example.
@konard konard changed the title [WIP] Readonly or mutable engine as per user configuration Readonly or mutable engine as per user configuration Jun 10, 2026
@konard konard marked this pull request as ready for review June 10, 2026 23:40
@konard

konard commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

Working session summary

Working tree is clean. The implementation is complete. Here's a summary of what was done for issue #49.

Summary

Implemented R-1 / S-1 from the issue #47 case study: a read-only or mutable engine selected by user configuration. PR #65 is updated and marked ready; all CI checks pass.

Changes

src/configuration.rs — Added AccessMode { Mutable, ReadOnly } (with label/is_mutable/is_read_only) and wired it into ParseConfiguration via with_access_mode() / access_mode(). Default is Mutable, so existing callers see no behavior change.

src/access.rs (new) — The access-control boundary:

  • ReadOnlyNetwork — a frozen view produced by LinkNetwork::freeze() / as_read_only(). It Derefs to &LinkNetwork, exposing every non-mutating operation while leaving the &mut self mutators unreachable at compile time (no DerefMut). Held behind an Arc so clones share one allocation. Includes to_mutable / into_mutable to fork back to an editable network.
  • EngineNetwork + LinkNetwork::parse_engine() — the runtime boundary honouring the configured access mode. Read-only parsing returns the frozen form, and as_mutable() rejects mutation with a clear ReadOnlyViolation diagnostic.

src/snapshots.rsNetworkSnapshot::as_read_only() / from_read_only() reuse the snapshot's Arc<LinkNetwork>, so the frozen form composes with snapshot versioning instead of duplicating it.

Tests (tests/unit/access_mode.rs, 8 tests) — cover freeze → query/reconstruct/verify, default-mutable config, Arc sharing across clones, forking back to mutable, parse_engine in both modes, runtime ReadOnlyViolation, snapshot interop, and mode round-trips. A compile_fail doctest in access.rs documents that mutation cannot compile.

Docs — README feature bullet + usage example; changelog fragment (bump: minor).

Acceptance criteria — all met

  • ParseConfiguration carries an access mode; default Mutable
  • ✅ Read-only view supports every non-mutating operation and none of the mutating ones (compile-time enforced)
  • ✅ Tests cover freeze/query/reconstruct, compile-fail + runtime mutation rejection, snapshot interop
  • ✅ Changelog fragment (bump: minor)

Note on a CI fix mid-way

The first push failed the file-size guard because parse_engine pushed src/link_network.rs to 1004 lines (limit 1000). I moved that method into the access.rs impl LinkNetwork block, bringing it back to 987 lines; the subsequent run is green.


This summary was automatically extracted from the AI working session output.

@konard

konard commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost: $4.035761

📊 Context and tokens usage:

  • 105.1K / 1M (11%) input tokens, 30.5K / 128K (24%) output tokens

Total: (8.5K new + 92.2K cache writes + 5.3M cache reads) input tokens, 30.5K output tokens, $4.035761 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.8 (claude-opus-4-8)

📎 Log file uploaded as Gist (1911KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

🔄 Auto-restart triggered (iteration 1)

Reason: Merge conflicts detected

Starting new session to address the issues.


Auto-restart-until-mergeable mode is active. This run will stop after 5 restart iterations.

@konard

konard commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

Working session summary

The merge conflicts are resolved and everything is verified clean.

Summary

The PR #65 had merge conflicts against its base branch issue-47-76af108c0f24 (not main — this PR is part of the issue #47 stack). I resolved them:

Conflicts resolved (2):

  1. .gitkeep — a modify/delete conflict. The base branch intentionally removed this PR-creation placeholder (commit 56cd745 "chore: remove .gitkeep PR-creation placeholder"), while my branch had touched it. I honored the deletion.
  2. src/lib.rs — auto-merged cleanly; I verified the access-module wiring (pub mod access; and the EngineNetwork, ReadOnlyNetwork, ReadOnlyViolation re-exports) survived intact.

The base branch also brought in the data-exchange format grammars work (JSON/YAML/TOML/XML/INI/protobuf/GraphQL), which merged without issue.

Verification:

  • cargo build --all-features
  • cargo test --all-features — 128 passed, 0 failed, plus both access-mode doctests (including the compile_fail mutation test) ✅
  • cargo fmt --check
  • cargo clippy --all-targets --all-features — clean ✅
  • All CI checks green: Build, Lint/Format, Code Coverage, Tests on ubuntu/macos/windows, Changelog Fragment Check, Version Modification Check (release/deploy jobs correctly skipped — they only run on the default branch).

Final PR status: mergeable: MERGEABLE, mergeStateStatus: CLEAN.

Merge commit b1419cb pushed to issue-49-3a3011bb1089. PR: #65


This summary was automatically extracted from the AI working session output.

@konard

konard commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

🔄 Auto-restart-until-mergeable Log (iteration 1)

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost: $0.552220

📊 Context and tokens usage:

  • 33.2K / 1M (3%) input tokens, 4.8K / 128K (4%) output tokens

Total: (2.7K new + 20.4K cache writes + 583.3K cache reads) input tokens, 4.8K output tokens, $0.552220 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.8 (claude-opus-4-8)

📎 Log file uploaded as Gist (2442KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard konard merged commit 7a134e4 into issue-47-76af108c0f24 Jun 11, 2026
13 checks passed
@konard

konard commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

🎉 Auto-merged

This pull request has been automatically merged by hive-mind.

  • All CI checks have passed

Auto-merged by hive-mind with --auto-merge flag

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant